/**
 * 
 */
package edu.ou.cs.youming;

import java.io.File;
import java.io.FileWriter;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

import edu.ou.cs.youming.agents.Agent;
import edu.ou.cs.youming.agents.DTAgent;
import edu.ou.cs.youming.agents.HeuristicAgent;
import edu.ou.cs.youming.agents.RandomAgent;
import edu.ou.cs.youming.jaxb.types.Example;
import edu.ou.cs.youming.jaxb.types.Label;
import edu.ou.cs.youming.jaxb.types.Results;
import edu.ou.cs.youming.services.DataIO;
import edu.ou.cs.youming.services.Services;

/**
 * @author Youming Lin
 * 
 */
public final class Main {
	private static final String corpusPath = "D:/Cruzer USB/Fall 2012/CS 5033/Project/corpus.csv";
	private static final String dir = "D:/Cruzer USB/Fall 2012/CS 5033/Project/rawdata/";
	private static final EnumSet<Label> labels = EnumSet.of(Label.POSITIVE,
			Label.NEGATIVE);
	private static final int k = 5;

	/**
	 * @param args
	 * @throws Exception
	 */
	public static void main(final String[] args) throws Exception {
		// create results directory for saving validation results
		final File folder = new File("results");
		folder.mkdir();
		final PrintWriter out = new PrintWriter(new FileWriter(folder.getAbsolutePath()
				+ File.separator + "results3.csv"));

		// //////////////////////////////////////////////////////////////////////////////
		// parse data set
		final long startTime = System.nanoTime();
		final ArrayList<Example> examples = (ArrayList<Example>) DataIO.parseExamples(
				corpusPath, dir);
		final long endTime = System.nanoTime();

		System.out.println("Parsing " + examples.size() + " examples took "
				+ (endTime - startTime) / 1000000000.0 + "s.");

		// //////////////////////////////////////////////////////////////////////////////
		// keep only POSITIVE and NEGATIVE labels
		for (final Iterator<Example> itr = examples.iterator(); itr.hasNext();) {
			if (!labels.contains(itr.next().polarity)) {
				itr.remove();
			}
		}

		// //////////////////////////////////////////////////////////////////////////////
		// create agents
		final ArrayList<Agent> agents = new ArrayList<Agent>();
		agents.add(new RandomAgent(labels));
		agents.add(new HeuristicAgent());
		agents.add(new DTAgent(Label.POSITIVE));

		// //////////////////////////////////////////////////////////////////////////////
		// get k-fold cross validation results
		for (double threshold = 2d; threshold < 20d; ++threshold) {
			out.println("Threshold, Fold #, Agent, Label, Training Set, Validation Set, Correct Predictions");

			final Map<Integer, ? extends Iterable<Results>> results = Services
					.crossValidate(examples, agents, threshold, k);

			for (final Entry<Integer, ? extends Iterable<Results>> e : results.entrySet()) {
				for (final Results r : e.getValue()) {
					for (final Label l : labels) {
						final Integer tSetFreq = r.tSetDist.get(l);
						final Integer vSetFreq = r.vSetDist.get(l);
						final Integer pFreq = r.pDist.get(l);

						out.println(threshold + "," + e.getKey() + ","
								+ r.agent.getClass().getSimpleName() + "," + l + ","
								+ ((tSetFreq == null) ? 0 : tSetFreq) + ","
								+ ((vSetFreq == null) ? 0 : vSetFreq) + ","
								+ ((pFreq == null) ? 0 : pFreq));
					}
				}
			}

			out.println();
		}

		out.close();
		System.out.println("Done");
	}
}